package cn.legym.garp.gateway.traffic.rule;

import cn.legym.garp.gateway.traffic.dynamic.bean.DynamicResourceDefinition;
import lombok.Data;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;


/**
 * create by pipisun on 2021/9/6
 * copyright © 2017-2021 Legym Technology Co.,Ltd. All rights reserve
 * d.
 * file description:
 * <p>
 * 自定义请求转义规则。检查一个请求是否符合预定义pattern，并提供可用的 自定义 或 Sentinel预定义 的资源名称。
 *
 * <p>
 *     e.g.
 *     <code>
 *     有自定义规则：{urlPattern:'/foo/bar/**', resource: 'target_res'},
 *     收到请求路径如： http://some.web.site/foo/bar/886
 *     可以匹配成功
 *     </code>
 * <p>
 *
 * 执行流程：
 * 收到网络请求后，经Spring Cloud Gateway的Filter过滤，将由{@link TrafficRuleManager}解析{@link ServerHttpRequest}。
 * 如果请求路径符合预定义pattern，随后会取resource作为转义结果。resource指向Sentinel中定义的资源或自定义资源。
 * 由{@link TrafficRule#dynamicResource}决定是否使用自定义资源规则。
 * 当指向自定义资源时，{@link TrafficRule#resource}需要和{@link DynamicResourceDefinition}结合参数动态生成的名字一致。
 * <p>
 * last update by {} on {}
 * update description:
 *
 * @see TrafficRuleManager
 */
@Data
public class TrafficRule {

    /**
     * 路径源匹配
     */
    private String urlPattern;

    /**
     * 路径转换目标 可以是一个 Sentinel资源名称 或 自定义资源名称
     *
     * @see DynamicResourceDefinition#getName()
     */
    private String resource;
    /**
     * 是否使用自定义动态资源
     */
    private Boolean dynamicResource;

    private PathMatcher pathMatcher;

    public void init() {
        pathMatcher = new AntPathMatcher();
    }

    /**
     * 检查一个请求是否符合当前规则
     *
     * @param request 请求
     * @return 匹配结果
     */
    public boolean matchRule(ServerHttpRequest request) {
        return pathMatcher.match(urlPattern, request.getPath().value());
    }
}
